<h2>Why is this an issue?</h2>
<p>When calling the <code>BeginInvoke</code> method of a <a href="https://learn.microsoft.com/en-us/dotnet/api/system.delegate">delegate</a>,
resources are allocated that are only freed up when <code>EndInvoke</code> is called. Failing to pair <code>BeginInvoke</code> with
<code>EndInvoke</code> can lead to <a href="https://en.wikipedia.org/wiki/Resource_leak">resource leaks</a> and incomplete asynchronous calls.</p>
<p>This rule raises an issue in the following scenarios:</p>
<ul>
  <li> The <code>BeginInvoke</code> method is called without any callback, and it is not paired with a call to <code>EndInvoke</code> in the same
  block. </li>
  <li> A callback with a single parameter of type <code>IAsyncResult</code> does not contain a call to <code>EndInvoke</code> in the same block. </li>
</ul>
<h2>How to fix it</h2>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<p><code>BeginInvoke</code> without callback:</p>
<pre data-diff-id="1" data-diff-type="noncompliant">
Public Delegate Function AsyncMethodCaller() As String

Public Class Sample

    Public Sub DoSomething()
        Dim Example As New AsyncExample()
        Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
        ' Initiate the asynchronous call.
        Dim Result As IAsyncResult = Caller.BeginInvoke(Nothing, Nothing) ' Noncompliant: Not paired With EndInvoke
    End Sub

End Class
</pre>
<p><code>BeginInvoke</code> with callback:</p>
<pre data-diff-id="2" data-diff-type="noncompliant">
Public Delegate Function AsyncMethodCaller() As String

Public Class Sample

    Public Sub DoSomething()
        Dim Example As New AsyncExample()
        Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
        ' Initiate the asynchronous call.
        Dim Result As IAsyncResult = Caller.BeginInvoke(New AsyncCallback(Sub(ar)
                                                                          End Sub), Nothing) ' Noncompliant: Not paired With EndInvoke
    End Sub

End Class
</pre>
<h4>Compliant solution</h4>
<p><code>BeginInvoke</code> without callback:</p>
<pre data-diff-id="1" data-diff-type="compliant">
Public Delegate Function AsyncMethodCaller() As String

Public Class Sample

    Public Function DoSomething() As String
        Dim Example As New AsyncExample()
        Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
        ' Initiate the asynchronous call.
        Dim Result As IAsyncResult = Caller.BeginInvoke(Nothing, Nothing)
        ' ...
        Return Caller.EndInvoke(Result)
    End Function

End Class
</pre>
<p><code>BeginInvoke</code> with callback:</p>
<pre data-diff-id="2" data-diff-type="compliant">
Public Delegate Function AsyncMethodCaller() As String

Public Class Sample

    Public Sub DoSomething()
        Dim Example As New AsyncExample()
        Dim Caller As New AsyncMethodCaller(Example.SomeMethod)
        ' Initiate the asynchronous call.
        Dim Result As IAsyncResult = Caller.BeginInvoke(New AsyncCallback(Sub(ar)
                                                                              ' Call EndInvoke to retrieve the results.
                                                                              Dim Ret As String = Caller.EndInvoke(ar)
                                                                              ' ...
                                                                          End Sub), Nothing)
    End Sub

End Class
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously">Calling
  Synchronous Methods Asynchronously</a> </li>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-using-delegates">Asynchronous
  Programming Using Delegates</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.begininvoke">BeginInvoke()</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.endinvoke">EndInvoke()</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.asynccallback">AsyncCallback Delegate</a> </li>
</ul>

